if (!Array.prototype.flat) {
  Array.prototype.flat = function (number = 1) {
    const array = this
    const res = []
    const getFlatArray = (array, _number) => {
      if (_number < 0) {
        res.push(array)
        return
      }
      array.forEach((item) => {
        if (Object.prototype.toString.call(item) == '[object Array]') {
          getFlatArray(item, _number - 1)
        } else {
          res.push(item)
        }
      })
    }
    getFlatArray(array, number)
    return res
  }
}

/**
 * 获取当前时间
 * @returns
 */
export const getTime = () => {
  return new Date().getTime()
}

/**
 * 格式化时间戳
 * @param {*} time 时间戳
 * @param {*} pattern 返回格式
 * @returns
 */
export const parseTime = (time, pattern) => {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
      time = parseInt(time)
    } else if (typeof time === 'string') {
      time = time
        .replace(new RegExp(/-/gm), '/')
        .replace('T', ' ')
        .replace(new RegExp(/\.[\d]{3}/gm), '')
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

/**
 * 格式化时间戳-习题中心
 * @param {*} timestamp 时间戳
 * @returns
 */
export const formatTimeStamp = (timestamp) => {
  // 时间戳为10位需*1000，时间戳为13位的话不需乘1000
  const date = new Date(timestamp)
  const year = date.getFullYear(),
    month = ('0' + (date.getMonth() + 1)).slice(-2),
    sdate = ('0' + date.getDate()).slice(-2),
    hour = ('0' + date.getHours()).slice(-2),
    minute = ('0' + date.getMinutes()).slice(-2),
    second = ('0' + date.getSeconds()).slice(-2)

  // 拼接
  const result = year + '-' + month + '-' + sdate + ' ' + hour + ':' + minute + ':' + second

  return result
}

/**
 * 格式化时间-习题中心
 * @param {*} num 秒数
 * @returns
 */
export const formatSeconds = (num) => {
  const seconds = parseInt(num)
  const h =
    Math.floor(seconds / 3600) < 10 ? '0' + Math.floor(seconds / 3600) : Math.floor(seconds / 3600)
  const m =
    Math.floor((seconds / 60) % 60) < 10
      ? '0' + Math.floor((seconds / 60) % 60)
      : Math.floor((seconds / 60) % 60)
  const s =
    Math.floor(seconds % 60) < 10 ? '0' + Math.floor(seconds % 60) : Math.floor(seconds % 60)

  let result = ''
  if (h !== '00') result += `${h}:`
  if (m !== '00') {
    result += `${m}:`
  } else {
    result += '00:'
  }
  result += `${s}`

  return result
}

/**
 * 图片转base64
 * @param {*} url 图片地址
 * @returns
 */
export const urlTobase64 = (url) => {
  return new Promise((resolve, reject) => {
    // #ifdef MP-WEIXIN
    uni.getFileSystemManager().readFile({
      filePath: url, // 选择图片返回的相对路径
      encoding: 'base64', // 编码格式
      success: (res) => {
        // 成功的回调

        const base64 = res.data
        resolve(base64)
      },
      fail: (e) => {
        reject('图片转换失败')
      }
    })
    // #endif

    // #ifndef MP-WEIXIN
    uni.request({
      url: url,
      method: 'GET',
      responseType: 'arraybuffer',
      success: (ress) => {
        const base64 = wx.arrayBufferToBase64(ress.data) // 把arraybuffer转成base64
        resolve(base64)
      },
      fail: (e) => {
        reject('图片转换失败')
      }
    })
    // #endif
  })
}

/**
 * 函数防抖
 * @param {*} func 目标函数
 * @param {*} wait 延迟执行毫秒数
 * @param {*} immediate true - 立即执行， false - 延迟执行
 * @returns
 */
export const debounce = function (func, wait = 1000, immediate = true) {
  let timer
  return function (...args) {
    let context = this
    if (timer) clearTimeout(timer)
    if (immediate) {
      let callNow = !timer
      timer = setTimeout(() => {
        timer = null
      }, wait)
      if (callNow) func.call(context, ...args)
    } else {
      timer = setTimeout(() => {
        func.call(context, ...args)
      }, wait)
    }
  }
}

/**
 * 初始化element-ui Message
 * @param {*} Message Message构造函数
 * @returns
 */
export const initMessage = (Message) => {
  const $message = (options) => {
    return Message({
      ...options,
      offset: 100
    })
  }

  ;['success', 'warning', 'info', 'error'].forEach((type) => {
    $message[type] = (options) => {
      if (typeof options === 'string') {
        options = {
          message: options,
          offset: 100
        }
      }
      options.type = type
      return Message(options)
    }
  })

  return $message
}

/**
 * 上传文件
 * @param {*} accept 支持的文件格式，如：image/*
 * @param {*} multiple 是否支持多选
 * @returns
 */
export const uploadFile = (accept, multiple = false) => {
  return new Promise((resove) => {
    const elementA = document.createElement('input')
    document.body.appendChild(elementA)
    elementA.type = 'file'
    // elementA.accept= accept;//"image/*"  错误用法
    elementA.setAttribute('accept', accept) //正确用法

    if (multiple) {
      elementA.multiple = true
    }
    elementA.style.display = 'none'
    elementA.onchange = () => {
      if (elementA.files && elementA.files.length > 0) {
        resove(elementA.files)
      }
    }
    elementA.click()
    document.body.removeChild(elementA)
  })
}

/**
 * 图片转base64
 * @param {*} url 图片路径
 * @returns
 */
export const imageToBase64 = async (url) => {
  return new Promise((resolve, reject) => {
    const image = new Image()
    image.src = url
    image.onload = () => {
      const canvas = document.createElement('canvas')
      canvas.width = image.naturalWidth // 使用 naturalWidth 为了保证图片的清晰度
      canvas.height = image.naturalHeight
      canvas.style.width = `${canvas.width / window.devicePixelRatio}px`
      canvas.style.height = `${canvas.height / window.devicePixelRatio}px`
      const ctx = canvas.getContext('2d')
      if (!ctx) {
        return null
      }
      ctx.drawImage(image, 0, 0)
      const base64 = canvas.toDataURL('image/png')
      return resolve(base64)
    }
    image.onerror = (err) => {
      return reject(err)
    }
  })
}

/**
 * 上传图片，返回图片base64
 * @returns
 */
export const uploadImage = () => {
  return new Promise(async (resolve) => {
    const [file] = await uploadFile('image/*', true)
    const url = URL.createObjectURL(file)
    const base64 = await imageToBase64(url)
    resolve(base64)
  })
}

/**
 * 判断是否有网
 */
export const isHaveNetwork = () => {
  return navigator.onLine
}

/**
 * 获取文件名
 * @param {*} fileUrl 文件路径
 * @returns
 */
export const getFileName = (fileUrl) => {
  const index = fileUrl.lastIndexOf('/')
  const fileName = decodeURI(fileUrl.slice(index + 1))

  return fileName
}

/**
 * 获取文件后缀名
 * @param {*} fileUrl 文件路径
 * @returns
 */
export const getFileSuffix = (fileUrl) => {
  const index = fileUrl.lastIndexOf('.')
  const suffix = fileUrl.slice(index + 1)

  return suffix
}

/**
 * 获取视频文件封面
 * @param {*} fileUrl 文件路径
 * @param {*} scale 缩放比例
 * @returns
 */
export const getVideoCover = (fileUrl, scale = 1) => {
  return new Promise((resolve) => {
    const video = document.createElement('video')
    video.crossOrigin = 'Anonymous'
    video.src = fileUrl
    video.currentTime = 1 // 获取第一帧的图片
    video.addEventListener('loadeddata', function () {
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      canvas.width = video.videoWidth * scale
      canvas.height = video.videoHeight * scale
      ctx.drawImage(this, 0, 0, canvas.width, canvas.height)

      resolve(canvas.toDataURL('image/png'))
    })
  })
}
